package com.lifeverse.entity;

import jakarta.persistence.*;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 群体决策实体类
 * 记录群体的决策过程和结果
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "group_decisions", indexes = {
    @Index(name = "idx_decision_group", columnList = "group_id"),
    @Index(name = "idx_decision_status", columnList = "decision_status"),
    @Index(name = "idx_decision_type", columnList = "decision_type"),
    @Index(name = "idx_decision_priority", columnList = "priority_level")
})
public class GroupDecision extends BaseEntity {
    
    /**
     * 决策类型枚举
     */
    public enum DecisionType {
        STRATEGIC("战略决策", "关于群体长期发展的重大决策"),
        OPERATIONAL("运营决策", "关于日常运营的决策"),
        RESOURCE("资源决策", "关于资源分配的决策"),
        MEMBERSHIP("成员决策", "关于成员加入或离开的决策"),
        POLICY("政策决策", "关于群体政策制定的决策"),
        CONFLICT("冲突决策", "关于冲突解决的决策"),
        INNOVATION("创新决策", "关于创新项目的决策"),
        COLLABORATION("协作决策", "关于对外协作的决策"),
        EMERGENCY("紧急决策", "紧急情况下的决策"),
        ROUTINE("常规决策", "日常例行决策");
        
        private final String displayName;
        private final String description;
        
        DecisionType(String displayName, String description) {
            this.displayName = displayName;
            this.description = description;
        }
        
        public String getDisplayName() {
            return displayName;
        }
        
        public String getDescription() {
            return description;
        }
    }
    
    /**
     * 决策状态枚举
     */
    public enum DecisionStatus {
        PROPOSED("已提议", "决策已被提出"),
        DISCUSSING("讨论中", "决策正在讨论中"),
        VOTING("投票中", "决策正在投票中"),
        APPROVED("已通过", "决策已被通过"),
        REJECTED("已拒绝", "决策已被拒绝"),
        IMPLEMENTED("已实施", "决策已被实施"),
        CANCELLED("已取消", "决策已被取消"),
        DEFERRED("已延期", "决策已被延期");
        
        private final String displayName;
        private final String description;
        
        DecisionStatus(String displayName, String description) {
            this.displayName = displayName;
            this.description = description;
        }
        
        public String getDisplayName() {
            return displayName;
        }
        
        public String getDescription() {
            return description;
        }
    }
    
    /**
     * 优先级枚举
     */
    public enum PriorityLevel {
        LOW("低", 1),
        MEDIUM("中", 2),
        HIGH("高", 3),
        URGENT("紧急", 4),
        CRITICAL("关键", 5);
        
        private final String displayName;
        private final int level;
        
        PriorityLevel(String displayName, int level) {
            this.displayName = displayName;
            this.level = level;
        }
        
        public String getDisplayName() {
            return displayName;
        }
        
        public int getLevel() {
            return level;
        }
    }
    
    /**
     * 所属群体
     */
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "group_id", nullable = false)
    private LifeEntityGroup group;
    
    /**
     * 决策标题
     */
    @Column(name = "title", nullable = false, length = 200)
    private String title;
    
    /**
     * 决策描述
     */
    @Column(name = "description", columnDefinition = "TEXT")
    private String description;
    
    /**
     * 决策类型
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "decision_type", nullable = false, length = 20)
    private DecisionType decisionType;
    
    /**
     * 决策状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "decision_status", nullable = false, length = 20)
    private DecisionStatus decisionStatus = DecisionStatus.PROPOSED;
    
    /**
     * 优先级
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "priority_level", nullable = false, length = 10)
    private PriorityLevel priorityLevel = PriorityLevel.MEDIUM;
    
    /**
     * 决策提议者
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "proposer_id")
    private LifeEntity proposer;
    
    /**
     * 决策选项（JSON格式）
     */
    @Column(name = "options", columnDefinition = "TEXT")
    private String options;
    
    /**
     * 投票结果（JSON格式）
     */
    @Column(name = "voting_results", columnDefinition = "TEXT")
    private String votingResults;
    
    /**
     * 决策算法类型
     */
    @Column(name = "algorithm_type", length = 50)
    private String algorithmType;
    
    /**
     * 算法参数（JSON格式）
     */
    @Column(name = "algorithm_parameters", columnDefinition = "TEXT")
    private String algorithmParameters;
    
    /**
     * 参与投票的成员数量
     */
    @Column(name = "participants_count", nullable = false)
    private Integer participantsCount = 0;
    
    /**
     * 支持票数
     */
    @Column(name = "support_votes", nullable = false)
    private Integer supportVotes = 0;
    
    /**
     * 反对票数
     */
    @Column(name = "oppose_votes", nullable = false)
    private Integer opposeVotes = 0;
    
    /**
     * 弃权票数
     */
    @Column(name = "abstain_votes", nullable = false)
    private Integer abstainVotes = 0;
    
    /**
     * 支持率（0-100）
     */
    @Column(name = "support_rate", nullable = false, precision = 5, scale = 2)
    private BigDecimal supportRate = BigDecimal.ZERO;
    
    /**
     * 决策置信度（0-100）
     */
    @Column(name = "confidence_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal confidenceScore = BigDecimal.valueOf(50.00);
    
    /**
     * 决策质量评分（0-100）
     */
    @Column(name = "quality_score", nullable = false, precision = 5, scale = 2)
    private BigDecimal qualityScore = BigDecimal.valueOf(50.00);
    
    /**
     * 预期影响评分（-100到100）
     */
    @Column(name = "expected_impact", nullable = false, precision = 6, scale = 2)
    private BigDecimal expectedImpact = BigDecimal.ZERO;
    
    /**
     * 实际影响评分（-100到100）
     */
    @Column(name = "actual_impact", precision = 6, scale = 2)
    private BigDecimal actualImpact;
    
    /**
     * 决策成本
     */
    @Column(name = "decision_cost", precision = 12, scale = 2)
    private BigDecimal decisionCost;
    
    /**
     * 预期收益
     */
    @Column(name = "expected_benefit", precision = 12, scale = 2)
    private BigDecimal expectedBenefit;
    
    /**
     * 实际收益
     */
    @Column(name = "actual_benefit", precision = 12, scale = 2)
    private BigDecimal actualBenefit;
    
    /**
     * 决策风险评估
     */
    @Column(name = "risk_assessment", columnDefinition = "TEXT")
    private String riskAssessment;
    
    /**
     * 决策依据
     */
    @Column(name = "rationale", columnDefinition = "TEXT")
    private String rationale;
    
    /**
     * 决策约束条件
     */
    @Column(name = "constraints", columnDefinition = "TEXT")
    private String constraints;
    
    /**
     * 决策标签
     */
    @Column(name = "tags", length = 200)
    private String tags;
    
    /**
     * 决策属性
     */
    @Column(name = "attributes", columnDefinition = "TEXT")
    private String attributes;
    
    /**
     * 决策提议时间
     */
    @Column(name = "proposed_at", nullable = false)
    private LocalDateTime proposedAt;
    
    /**
     * 投票开始时间
     */
    @Column(name = "voting_started_at")
    private LocalDateTime votingStartedAt;
    
    /**
     * 投票结束时间
     */
    @Column(name = "voting_ended_at")
    private LocalDateTime votingEndedAt;
    
    /**
     * 决策通过时间
     */
    @Column(name = "approved_at")
    private LocalDateTime approvedAt;
    
    /**
     * 决策实施时间
     */
    @Column(name = "implemented_at")
    private LocalDateTime implementedAt;
    
    /**
     * 决策截止时间
     */
    @Column(name = "deadline")
    private LocalDateTime deadline;
    
    /**
     * 是否需要一致同意
     */
    @Column(name = "requires_consensus", nullable = false)
    private Boolean requiresConsensus = false;
    
    /**
     * 最小参与率要求（0-100）
     */
    @Column(name = "min_participation_rate", nullable = false, precision = 5, scale = 2)
    private BigDecimal minParticipationRate = BigDecimal.valueOf(50.00);
    
    /**
     * 最小支持率要求（0-100）
     */
    @Column(name = "min_support_rate", nullable = false, precision = 5, scale = 2)
    private BigDecimal minSupportRate = BigDecimal.valueOf(50.00);
    
    @PrePersist
    protected void onCreate() {
        super.onCreate();
        if (proposedAt == null) {
            proposedAt = LocalDateTime.now();
        }
    }
    
    /**
     * 开始投票
     */
    public void startVoting() {
        this.decisionStatus = DecisionStatus.VOTING;
        this.votingStartedAt = LocalDateTime.now();
    }
    
    /**
     * 结束投票
     */
    public void endVoting() {
        this.votingEndedAt = LocalDateTime.now();
        calculateSupportRate();
        
        // 根据投票结果确定状态
        if (isApproved()) {
            this.decisionStatus = DecisionStatus.APPROVED;
            this.approvedAt = LocalDateTime.now();
        } else {
            this.decisionStatus = DecisionStatus.REJECTED;
        }
    }
    
    /**
     * 实施决策
     */
    public void implement() {
        this.decisionStatus = DecisionStatus.IMPLEMENTED;
        this.implementedAt = LocalDateTime.now();
    }
    
    /**
     * 取消决策
     */
    public void cancel() {
        this.decisionStatus = DecisionStatus.CANCELLED;
    }
    
    /**
     * 延期决策
     */
    public void defer() {
        this.decisionStatus = DecisionStatus.DEFERRED;
    }
    
    /**
     * 计算支持率
     */
    public void calculateSupportRate() {
        if (participantsCount > 0) {
            this.supportRate = BigDecimal.valueOf(supportVotes)
                    .divide(BigDecimal.valueOf(participantsCount), 4, java.math.RoundingMode.HALF_UP)
                    .multiply(BigDecimal.valueOf(100));
        }
    }
    
    /**
     * 判断决策是否通过
     */
    public boolean isApproved() {
        boolean hasMinParticipation = getParticipationRate().compareTo(minParticipationRate) >= 0;
        boolean hasMinSupport = supportRate.compareTo(minSupportRate) >= 0;
        boolean hasConsensus = !requiresConsensus || opposeVotes == 0;
        
        return hasMinParticipation && hasMinSupport && hasConsensus;
    }
    
    /**
     * 获取参与率
     */
    public BigDecimal getParticipationRate() {
        if (group != null && group.getMemberCount() > 0) {
            return BigDecimal.valueOf(participantsCount)
                    .divide(BigDecimal.valueOf(group.getMemberCount()), 4, java.math.RoundingMode.HALF_UP)
                    .multiply(BigDecimal.valueOf(100));
        }
        return BigDecimal.ZERO;
    }
    
    /**
     * 判断决策是否过期
     */
    public boolean isExpired() {
        return deadline != null && LocalDateTime.now().isAfter(deadline);
    }
    
    /**
     * 判断决策是否正在进行
     */
    public boolean isInProgress() {
        return decisionStatus == DecisionStatus.DISCUSSING || decisionStatus == DecisionStatus.VOTING;
    }
    
    /**
     * 判断决策是否已完成
     */
    public boolean isCompleted() {
        return decisionStatus == DecisionStatus.APPROVED || 
               decisionStatus == DecisionStatus.REJECTED ||
               decisionStatus == DecisionStatus.IMPLEMENTED ||
               decisionStatus == DecisionStatus.CANCELLED;
    }
    
    /**
     * 获取决策持续时间（小时）
     */
    public long getDurationHours() {
        LocalDateTime endTime = votingEndedAt != null ? votingEndedAt : LocalDateTime.now();
        return java.time.temporal.ChronoUnit.HOURS.between(proposedAt, endTime);
    }
    
    /**
     * 计算决策效率评分
     */
    public BigDecimal calculateEfficiencyScore() {
        long hours = getDurationHours();
        if (hours <= 1) return BigDecimal.valueOf(100);
        if (hours <= 24) return BigDecimal.valueOf(80);
        if (hours <= 72) return BigDecimal.valueOf(60);
        if (hours <= 168) return BigDecimal.valueOf(40);
        return BigDecimal.valueOf(20);
    }
}